package com.tobby.camelinaction.client;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.spi.Synchronization;
import org.apache.camel.support.SynchronizationAdapter;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;

public class RiderAutoPartsCallBackTest extends CamelTestSupport {

	private int numPartners = 5;

	@Override
	protected RouteBuilder createRouteBuilder() throws Exception {
		return new RouteBuilder() {

			@Override
			public void configure() throws Exception {
				// business partner routes with different delays
				// so some will answer within the period and others wont
				from("seda:partner:0").delay(500).transform().simple("bumper filter");
				from("seda:partner:1").delay(3000).transform().simple("nose panel");
				from("seda:partner:2").delay(1000).transform().simple("bumper cover");
				from("seda:partner:3").delay(250).transform().simple("bumper extension");
				from("seda:partner:4").delay(4000).transform().simple("tow hooks");
			}
		};
	}

	@Test
	public void testCallback() throws Exception {
		// related is the list of related items
		final List<String> relates = new ArrayList<String>();

		// latch to countdonw every time we got a reply
		final CountDownLatch latch = new CountDownLatch(numPartners);

		// use this callback to gather the replies and add it to the related list
		Synchronization callback = new SynchronizationAdapter() {
			public void onComplete(Exchange exchange) {
				// get the reply and add it to related
				String body = exchange.getOut().getBody(String.class);
				relates.add(body);

				log.info("Get async reply {}", body);

				// count down the latch
				latch.countDown();
			}
		};

		// send the same message to the business partners so they can return their feedback
		String body = "bumper";
		for (int i = 0; i < numPartners; i++) {
			template.asyncCallbackRequestBody("seda:partner:" + i, body, callback);
		}
		log.info("Send " + numPartners + " messages to partners.");

		// wait at most 2 seconds or until we got all replies
		boolean all = latch.await(2000, TimeUnit.MILLISECONDS);

		// log what we got as reply
		log.info("Got {} replies, is all? {}", relates.size(), all);
		for (String related : relates) {
			log.info("Related item category is: " + related);
		}

		// assert the unit test
		assertEquals(3, relates.size());
		assertEquals("bumper extension", relates.get(0));
		assertEquals("bumper filter", relates.get(1));
		assertEquals("bumper cover", relates.get(2));

	}

}
